/*
 * Controller for all client search operations.
 */
package com.cheapflix.controller;

import com.cheapflix.beans.DVD;
import com.cheapflix.beans.SearchCriteria;
import com.cheapflix.beans.User;
import com.cheapflix.beans.UserDVD;
import com.cheapflix.business.SearchManager;
import com.cheapflix.dao.DVDDao;
import com.cheapflix.dao.UserDVDDao;
import javax.servlet.http.HttpSession;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

/**
 * Controller class in charge of the various flick search functionalities.
 * @author Group B
 */
@Controller
public class SearchController {

    private static final Logger logger = Logger.getLogger(SearchController.class);
    private DVDDao dvdDao;
    private UserDVDDao udvdDao;
    private SearchManager searchMgr;

    /**
     * Initializes the controller
     * @param dvdDao - DAO for DVD queries
     * @param udvddao - DAO for UserDVD queries
     */
    @Autowired
    public void init(DVDDao dvdDao, UserDVDDao udvddao) {
        this.dvdDao = dvdDao;
        this.udvdDao = udvddao;
        searchMgr = new SearchManager(dvdDao);
    }

    /**
     * Controller for all basic 1 term DVD searches
     * @param searchField - Term to search on.
     * @param next - Whether to return the next set of results for this search.
     * @param prev - Whether to return the previous set of results for this search.
     * @param session - Current user session
     * @return - The SearchResults.jsp
     */
    @RequestMapping("/search")
    public ModelAndView search(@RequestParam("searchField") String searchField,
            @RequestParam(value = "next", required = false) String next,
            @RequestParam(value = "prev", required = false) String prev,
            HttpSession session) {

        logger.info("Search called");
        SearchCriteria criteria =
                (SearchCriteria) session.getAttribute("SearchCriteria");
        if (criteria == null) {
            criteria = new SearchCriteria();
        }
        if (next != null) {
            criteria = searchMgr.searchNext(criteria);
        } else if (prev != null) {
            criteria = searchMgr.searchPrev(criteria);
        } else {
            criteria = searchMgr.search(searchField, criteria);
        }

        session.setAttribute("SearchCriteria", criteria);

        return new ModelAndView("SearchResults");
    }

    /**
     * Controller method for an advanced search with multiple terms.
     * @param title - DVD title
     * @param actor - DVD actors
     * @param director - DVD director
     * @param genre - DVD genre
     * @param session - Current User session.
     * @return - The SearchResults.jsp
     */
    @RequestMapping("/advancedSearch")
    public ModelAndView advancedSearch(@RequestParam(value = "title", required = false) String title,
            @RequestParam(value = "actor", required = false) String actor,
            @RequestParam(value = "director", required = false) String director,
            @RequestParam(value = "genre", required = false) String genre,
            HttpSession session) {

        logger.info("Advanced Search");
        SearchCriteria criteria =
                (SearchCriteria) session.getAttribute("SearchCriteria");
        if (criteria == null) {
            criteria = new SearchCriteria();
        }
        criteria = searchMgr.advancedSearch(title, actor, director, genre, criteria);

        session.setAttribute("SearchCriteria", criteria);

        return new ModelAndView("SearchResults");
    }

    /**
     * Controller method when the user wants to show the advanced search page.
     * @return The AdvancedSearch.jsp
     */
    @RequestMapping("/searchAdvanced")
    public ModelAndView searchAdvanced() {
        logger.info("Go To Advanced DVD Search");
        return new ModelAndView("AdvancedSearch");
    }

    /**
     * Called when a user wants to show the details of a single DVD.
     * @param id - DVD id
     * @param session - Current user session.
     * @return - The DVDDetails.jsp
     */
    @RequestMapping("/searchId")
    public ModelAndView search(@RequestParam("id") int id, HttpSession session) {
        //Login logic goes here
        logger.info("------------- SearchID called for " + id +" --------------");
        DVD dvd = searchMgr.searchId(id);
        User me = (User) session.getAttribute("me");
        if(me==null){
            return new ModelAndView("redirect:/");
        }
        logger.info("me: "+ me);
        logger.info("dvd: " +dvd );
        UserDVD udvd = this.udvdDao.getUsersDVDQueueEntryByDVDID(me.getId(), dvd.getId());
        logger.info("Found User DVD: " + udvd);
        ModelAndView mav = new ModelAndView();
        mav.addObject("dvd", dvd);
        double avgRating = this.udvdDao.getGlobalAverageRatingForMovie(dvd.getId());
        double friendsAvgRating = this.udvdDao.getFriendsAverageRatingForMovie(dvd.getId(), me.getId());
        mav.addObject("avgRating", avgRating);
        mav.addObject("friendsAvgRating",friendsAvgRating);
        if (udvd != null) {
            mav.addObject("udvd", udvd);
        }
        mav.setViewName("/DvdDetails");
        return mav;
    }
}
